/* eslint-disable no-case-declarations */
/**
 * 处理微信相关的接口请求
 * 测试地址：https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index
 * 接口在线 debug: https://mp.weixin.qq.com/debug/
 */
import wechat from '../utils/weixin';
import getRawBody from 'raw-body';
import contentType from 'content-type';
import { xmlToJson } from '../utils';
import get from 'lodash/get';
import { Book, Secret, Setting } from '../models';
import { sendWxCardMsg } from '../utils/weixin/message';
import { makeBookIntro } from '../utils/generate-img';

export default function (router) {
  /**
   * 微信认证接口
   */
  router.get('/api/wechat', async ctx => {
    if (await wechat.jssdk.verifySignature(ctx.request.query)) {
      ctx.body = ctx.request.query.echostr;
      return false;
    }
    ctx.body = '非法请求';
  });

  /**
   * 微信消息监听接口
   */
  router.post('/api/wechat', async (ctx, next) => {
    try {
      const wxRes = await getRawBody(ctx.req, {
        length: ctx.req.headers['content-length'],
        limit: '1mb',
        encoding: contentType.parse(ctx.req).parameters.charset
      });

      const wxJson = await xmlToJson(wxRes.toString());
      console.log(wxRes.toString(), wxJson);

      const eventName = get(wxJson, 'xml.Event[0]');
      const msgType = get(wxJson, 'xml.MsgType[0]');
      const toUserName = get(wxJson, 'xml.ToUserName[0]');
      const fromUserName = get(wxJson, 'xml.FromUserName[0]');
      if (eventName) {
        switch (eventName) {
          case 'subscribe':
            /**
             * 用户关注公众号
             * 自动回复欢迎语
             */
            const autoReplySetting = await Setting.findOne({ key: 'focus_mp_account_auto_reply' }, 'value');
            ctx.type = 'xml';
            ctx.status = 200;
            ctx.body = `<xml><ToUserName><![CDATA[${fromUserName}]]></ToUserName>
            <FromUserName><![CDATA[${toUserName}]]></FromUserName>
            <CreateTime>${new Date().getTime()}</CreateTime>
            <MsgType><![CDATA[text]]></MsgType>
            <Content><![CDATA[${autoReplySetting.value || '请输入客服小姐姐给你的数字领取书籍'}]]></Content></xml>`;
            await next();
            break;
          default:
            break;
        }
      } else if (msgType) {
        switch (msgType) {
          case 'text':
            /**
             *  用户发送文字消息
             */
            const content = get(wxJson, 'xml.Content[0]') || '';
            const secretReg = /\d{6}/g;
            const matchResult = content.match(secretReg);
            let message = ''; // 即将回复的消息
            if (matchResult) {
              // 查询匹配的书籍
              const thisBook = await Book.findOne({ secret: matchResult[0] }, '_id name author img_url');
              if (!thisBook) {
                message = '解锁码错误，请重新输入';
              } else {
                try {
                  // 创建新的秘钥
                  const newSecret = await Secret.create({
                    bookid: ctx.transId(thisBook._id),
                    active: false,
                    create_time: new Date()
                  });
                  // 生成书籍介绍图片
                  let bookIntro = '';
                  try {
                    bookIntro = await makeBookIntro(thisBook._id);
                  } catch (err) {
                    console.log(`生成解锁图片失败，ID: ${thisBook._id}`);
                  }
                  // 发送解锁书籍的卡片
                  await sendWxCardMsg({
                    touser: fromUserName,
                    title: `${thisBook.name}, ${thisBook.author}`,
                    page: `/pages/bookdetail/index?id=${thisBook._id}&pre_secret=${newSecret._id}`,
                    imageUrl: bookIntro
                  });
                  message = `已为您解锁《${thisBook.name}》，点击下方卡片阅读吧`;
                } catch (err) {
                  message = `未能成功解锁《${thisBook.name}》，请联系微信客服`;
                }
              }
            } else {
              message = '解锁码错误，请重新输入';
            }
            ctx.type = 'xml';
            ctx.status = 200;
            ctx.body = `<xml><ToUserName><![CDATA[${fromUserName}]]></ToUserName>
            <FromUserName><![CDATA[${toUserName}]]></FromUserName>
            <CreateTime>${new Date().getTime()}</CreateTime>
            <MsgType><![CDATA[text]]></MsgType>
            <Content><![CDATA[${message}]]></Content></xml>`;
            await next();
            break;
          default:
            break;
        }
      }
    } catch (err) {
      // 不做回应
      console.log('微信消息解析失败', err);
    }
  });

  /**
   * 获取微信签名信息
   */
  router.get('/api/wechat/get-signature', async ctx => {
    return new Promise((resolve, reject) => {
      const { url = '' } = ctx.request.query;
      wechat.jssdk.getSignature(decodeURIComponent(url)).then(
        data => {
          ctx.body = { ok: true, data };
          resolve(data);
        },
        reason => {
          console.log(reason);
          ctx.body = { ok: false, data: reason };
          reject(new Error(reason.errmsg));
        }
      );
    });
  });

  router.get('/api/wechat/oauth-callback', async ctx => {
    // 得到code，获取基本用户信息openid
    return new Promise((resolve, reject) => {
      const { code = '' } = ctx.request.query;
      wechat.oauth.getUserBaseInfo(code).then(
        data => {
          ctx.body = { ok: true, data };
          // 判断当前用户是否已经注册过
          if (data.openid) resolve(data);
        },
        reason => {
          console.log(reason);
          ctx.body = { ok: false, data: reason };
          reject(new Error(reason.errmsg));
        }
      );
    });
  });
}
